package com.papper.common.service.sys;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.papper.common.bean.sys.SysLimit;
import com.papper.common.bean.sys.SysResource;
import com.papper.common.bean.sys.SysUser;
import com.papper.common.mapper.sys.SysResourceMapper;
import com.papper.common.service.ServiceImpl;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author:LaJiao
 * @Date:2017-08-03 14:31:11
 * @Description:系统模块资源表
 */
@Service("sysResourceService")
public class SysResourceService extends ServiceImpl<SysResourceMapper, SysResource> {
	@Resource
	SysLimitService sysLimitService;

	/**
	 * function
	 */
	public List<SysResource> findLimitBySystemId(Long systemId, SysUser sysUser) {
		// 超级用户
		if (sysUser.getId() == 0) {
			return findBySystem(systemId.toString());
		}
		// 获取权限信息
		List<SysLimit> userLimits = sysLimitService.getUserLimits(sysUser);
		Set<String>    ids        = Sets.newHashSet();
		if (userLimits != null && !userLimits.isEmpty()) {
			for (SysLimit sysLimit : userLimits) {
				ids.add(sysLimit.getResId().toString());
			}
		}
		// 获取资源列表
		return findByIds(ids);
	}

	public List<SysResource> findByLimit(Long modelId, SysUser sysUser) {
		// 超级用户
		if (sysUser.getId() == 0) {
			return findByMid(modelId);
		}
		// 获取权限信息
		List<SysLimit> userLimits = sysLimitService.getUserLimits(sysUser);
		Set<String>    ids        = Sets.newHashSet();
		if (userLimits != null && !userLimits.isEmpty()) {
			for (SysLimit sysLimit : userLimits) {
				ids.add(sysLimit.getResId().toString());
			}
		}
		// 获取资源列表
		return findByIds(ids);
	}

	public List<SysResource> findBySystem(String systemId) {
		Example example = new Example(SysResource.class);
		example.createCriteria().andEqualTo("systemId", systemId);
		return find(example);
	}

	public List<SysResource> findByMid(Long mid) {
		Example example = new Example(SysResource.class);
		example.createCriteria().andEqualTo("modelId", mid);
		return find(example);
	}

	public List<SysResource> findByIds(Set<String> ids) {
		if (ids == null || ids.isEmpty()) {
			return null;
		}
		String idsString = Joiner.on(",").skipNulls().join(ids);
		return findByIds(idsString);
	}

	public List<SysResource> treeGridSort(List<SysResource> sysResources) {
		if (sysResources == null || sysResources.isEmpty()) {
			return sysResources;
		}

		Map<String, String> sort = Maps.newHashMap();
		for (SysResource sysResource : sysResources) {
			sort.put(sysResource.getId().toString(), sysResource.getResSort().toString());
		}
		for (SysResource sysResource : sysResources) {
			String[]     arrays = sysResource.getUpFamily().split(",");
			List<String> sorts  = Lists.newArrayList();
			for (String s : arrays) {
				sorts.add(sort.get(s));
			}
			sysResource.setUpFamily(Joiner.on(",").skipNulls().join(sorts));
		}

		Collections.sort(sysResources, new Comparator<SysResource>() {
			@Override
			public int compare(SysResource o1, SysResource o2) {
				return o1.getUpFamily().compareTo(o2.getUpFamily());
			}
		});

		return sysResources;
	}

	public List<SysResource> treeChildList(List<SysResource> sysResources) {
		if (sysResources == null || sysResources.isEmpty()) {
			return sysResources;
		}
		sysResources = treeGridSort(sysResources);
		// 组装层级关系
		Map<Long, SysResource>          sysResourceMap = Maps.newLinkedHashMap();
		Map<Integer, List<SysResource>> levelMap       = Maps.newLinkedHashMap();
		int                             maxLevel       = 0;
		int                             minLevel       = 0;
		for (SysResource sysResource : sysResources) {
			sysResourceMap.put(sysResource.getId(), sysResource);
			Integer           resLevel  = Splitter.on(',').omitEmptyStrings().splitToList(sysResource.getUpFamily()).size();
			List<SysResource> levelTemp = levelMap.get(resLevel);
			if (levelTemp == null) {
				levelTemp = new ArrayList<SysResource>();
			}
			levelTemp.add(sysResource);
			levelMap.put(resLevel, levelTemp);
			if (resLevel > maxLevel || maxLevel == 0) {
				maxLevel = resLevel;
			}
			if (resLevel < minLevel || minLevel == 0) {
				minLevel = resLevel;
			}
		}
		for (int i = maxLevel; i >= minLevel; i--) {
			List<SysResource> levelTemp = levelMap.get(i);
			if (levelTemp != null) {
				for (SysResource sysResource : levelTemp) {
					if (sysResource.getUpId() == 0) {
						continue;
					}
					SysResource upResource = sysResourceMap.get(sysResource.getUpId().longValue());
					if (upResource == null) {
						continue;
					}
					if (upResource.getChilds() == null) {
						upResource.setChilds(new ArrayList<SysResource>());
					}
					upResource.getChilds().add(sysResource);
					Collections.sort(upResource.getChilds(), new Comparator<SysResource>() {
						@Override
						public int compare(SysResource o1, SysResource o2) {
							return o1.getResSort().compareTo(o2.getResSort());
						}
					});
					sysResourceMap.remove(sysResource.getId());
					sysResourceMap.put(sysResource.getUpId().longValue(), upResource);
					continue;
				}
			}
		}
		List<SysResource> listRtn = Lists.newArrayList();
		for (Long id : sysResourceMap.keySet()) {
			listRtn.add(sysResourceMap.get(id));
		}
		Collections.sort(listRtn, new Comparator<SysResource>() {
			@Override
			public int compare(SysResource o1, SysResource o2) {
				return o1.getResSort().compareTo(o2.getResSort());
			}
		});
		return listRtn;
	}

	public List<SysResource> findByChild(String childFamily, boolean self) {
		Example          example  = new Example(SysResource.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.orLike("upFamily", childFamily + ",%");
		if (self) {
			criteria.orEqualTo("upFamily", childFamily);
		}
		return find(example);
	}

	public void matchLevel(List<SysResource> sysResources) {
		if (sysResources == null || sysResources.size() <= 0) {
			return;
		}
		for (SysResource sysResource : sysResources) {
			sysResource.setResLevel(Splitter.on(',').omitEmptyStrings().splitToList(sysResource.getUpFamily()).size());
		}
	}

	public void matchFamily(SysResource sysResource) {
		if (sysResource == null) {
			return;
		}
		// 父结构树维护
		SysResource parent = findById(sysResource.getUpId());
		String      family;
		if (parent != null) {
			family = parent.getUpFamily() + "," + sysResource.getId();
		} else {
			family = "0," + sysResource.getId();
		}
		// 数据更新
		SysResource upd = new SysResource();
		upd.setId(sysResource.getId());
		upd.setUpFamily(family);
		update(upd);
		sysResource.setUpFamily(family);
	}

	public void matchChild(SysResource sysResource) {
		if (sysResource == null) {
			return;
		}
		// 子机构树维护
		Example example = new Example(SysResource.class);
		example.createCriteria().andEqualTo("upId", sysResource.getId());
		Integer resChile = count(example);
		// 数据更新
		SysResource upd = new SysResource();
		upd.setId(sysResource.getId());
		upd.setUpChild(resChile == null ? 0 : resChile.intValue());
		update(upd);
		sysResource.setUpChild(resChile == null ? 0 : resChile.intValue());
	}

	public void deleteWithChild(SysResource sysResource) {
		List<SysResource> childs = findByChild(sysResource.getUpFamily(), true);
		if (childs == null || childs.isEmpty()) {
			return;
		}
		for (SysResource resource : childs) {
			deleteById(resource.getId());
			sysLimitService.delLimitedByResId(resource.getId());
		}
	}
}